package controllers

import (
	"gorm.io/gorm"
	"log"
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"go-admin-system/models"
	"go-admin-system/utils"
)

type UserController struct {
	DB *gorm.DB
}

func NewUserController(db *gorm.DB) *UserController {
	return &UserController{DB: db}
}

// 创建用户
func (uc *UserController) CreateUser(c *gin.Context) {
	startTime := time.Now()

	var user models.User
	if err := c.ShouldBindJSON(&user); err != nil {
		log.Printf("创建用户 [参数绑定失败] - IP: %s, 耗时: %v, 错误: %v",
			c.ClientIP(), time.Since(startTime), err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数格式错误: " + err.Error()})
		return
	}

	log.Printf("创建用户 [开始处理] - 用户名: %s, 邮箱: %s, 角色ID: %d, IP: %s, 耗时: %v",
		user.Username, user.Email, user.RoleID, c.ClientIP(), time.Since(startTime))

	// 密码加密
	hashedPassword, err := utils.HashPassword(user.Password)
	if err != nil {
		log.Printf("创建用户 [密码加密失败] - 用户名: %s, IP: %s, 耗时: %v, 错误: %v",
			user.Username, c.ClientIP(), time.Since(startTime), err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "密码加密失败: " + err.Error()})
		return
	}
	user.Password = hashedPassword

	if err := uc.DB.Create(&user).Error; err != nil {
		log.Printf("创建用户 [数据库操作失败] - 用户名: %s, IP: %s, 耗时: %v, 错误: %v",
			user.Username, c.ClientIP(), time.Since(startTime), err)
		errorMsg := "创建用户失败: " + err.Error()
		c.JSON(http.StatusInternalServerError, gin.H{"error": errorMsg})
		return
	}

	log.Printf("创建用户 [成功] - 用户ID: %d, 用户名: %s, IP: %s, 总耗时: %v",
		user.ID, user.Username, c.ClientIP(), time.Since(startTime))

	c.JSON(http.StatusCreated, user)
}

// 获取用户列表
func (uc *UserController) GetUsers(c *gin.Context) {
	startTime := time.Now()

	var users []models.User
	if err := uc.DB.Preload("Role").Find(&users).Error; err != nil {
		log.Printf("获取用户列表 [数据库查询失败] - IP: %s, 耗时: %v, 错误: %v",
			c.ClientIP(), time.Since(startTime), err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取用户列表失败: " + err.Error()})
		return
	}

	log.Printf("获取用户列表 [成功] - 用户数量: %d, IP: %s, 耗时: %v",
		len(users), c.ClientIP(), time.Since(startTime))

	c.JSON(http.StatusOK, users)
}

// 获取单个用户
func (uc *UserController) GetUser(c *gin.Context) {
	startTime := time.Now()

	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		log.Printf("获取用户 [ID解析失败] - 请求ID: %s, IP: %s, 耗时: %v, 错误: %v",
			c.Param("id"), c.ClientIP(), time.Since(startTime), err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
		return
	}

	var user models.User
	if err := uc.DB.Preload("Role").First(&user, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			log.Printf("获取用户 [用户不存在] - 用户ID: %d, IP: %s, 耗时: %v",
				id, c.ClientIP(), time.Since(startTime))
			c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
		} else {
			log.Printf("获取用户 [数据库查询失败] - 用户ID: %d, IP: %s, 耗时: %v, 错误: %v",
				id, c.ClientIP(), time.Since(startTime), err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "查询用户失败: " + err.Error()})
		}
		return
	}

	log.Printf("获取用户 [成功] - 用户ID: %d, 用户名: %s, IP: %s, 耗时: %v",
		user.ID, user.Username, c.ClientIP(), time.Since(startTime))

	c.JSON(http.StatusOK, user)
}

// 更新用户
func (uc *UserController) UpdateUser(c *gin.Context) {
	startTime := time.Now()

	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		log.Printf("更新用户 [ID解析失败] - 请求ID: %s, IP: %s, 耗时: %v, 错误: %v",
			c.Param("id"), c.ClientIP(), time.Since(startTime), err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
		return
	}

	var user models.User
	if err := uc.DB.First(&user, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			log.Printf("更新用户 [用户不存在] - 用户ID: %d, IP: %s, 耗时: %v",
				id, c.ClientIP(), time.Since(startTime))
			c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
		} else {
			log.Printf("更新用户 [查询原用户失败] - 用户ID: %d, IP: %s, 耗时: %v, 错误: %v",
				id, c.ClientIP(), time.Since(startTime), err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "查询用户失败: " + err.Error()})
		}
		return
	}

	var updatedUser models.User
	if err := c.ShouldBindJSON(&updatedUser); err != nil {
		log.Printf("更新用户 [参数绑定失败] - 用户ID: %d, IP: %s, 耗时: %v, 错误: %v",
			id, c.ClientIP(), time.Since(startTime), err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数格式错误: " + err.Error()})
		return
	}

	// 记录更新前的信息
	oldUsername := user.Username
	oldEmail := user.Email
	oldRoleID := user.RoleID

	// 如果提供了新密码，则加密
	if updatedUser.Password != "" {
		hashStartTime := time.Now()
		hashedPassword, err := utils.HashPassword(updatedUser.Password)
		if err != nil {
			log.Printf("更新用户 [密码加密失败] - 用户ID: %d, 用户名: %s, IP: %s, 加密耗时: %v, 错误: %v",
				id, user.Username, c.ClientIP(), time.Since(hashStartTime), err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "密码加密失败: " + err.Error()})
			return
		}
		user.Password = hashedPassword
		log.Printf("更新用户 [密码加密成功] - 用户ID: %d, 用户名: %s, IP: %s, 加密耗时: %v",
			id, user.Username, c.ClientIP(), time.Since(hashStartTime))
	}

	user.Username = updatedUser.Username
	user.Email = updatedUser.Email
	user.Status = updatedUser.Status
	user.RoleID = updatedUser.RoleID

	if err := uc.DB.Save(&user).Error; err != nil {
		log.Printf("更新用户 [数据库保存失败] - 用户ID: %d, 原用户名: %s, 新用户名: %s, IP: %s, 耗时: %v, 错误: %v",
			id, oldUsername, user.Username, c.ClientIP(), time.Since(startTime), err)
		errorMsg := "更新用户失败: " + err.Error()
		c.JSON(http.StatusInternalServerError, gin.H{"error": errorMsg})
		return
	}

	log.Printf("更新用户 [成功] - 用户ID: %d, 原用户名: %s, 新用户名: %s, 原邮箱: %s, 新邮箱: %s, 原角色ID: %d, 新角色ID: %d, IP: %s, 总耗时: %v",
		id, oldUsername, user.Username, oldEmail, user.Email, oldRoleID, user.RoleID, c.ClientIP(), time.Since(startTime))

	c.JSON(http.StatusOK, user)
}

// 删除用户
func (uc *UserController) DeleteUser(c *gin.Context) {
	startTime := time.Now()

	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		log.Printf("删除用户 [ID解析失败] - 请求ID: %s, IP: %s, 耗时: %v, 错误: %v",
			c.Param("id"), c.ClientIP(), time.Since(startTime), err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
		return
	}

	var user models.User
	if err := uc.DB.First(&user, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			log.Printf("删除用户 [用户不存在] - 用户ID: %d, IP: %s, 耗时: %v",
				id, c.ClientIP(), time.Since(startTime))
			c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
		} else {
			log.Printf("删除用户 [查询用户失败] - 用户ID: %d, IP: %s, 耗时: %v, 错误: %v",
				id, c.ClientIP(), time.Since(startTime), err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "查询用户失败: " + err.Error()})
		}
		return
	}

	// 记录要删除的用户信息
	username := user.Username
	email := user.Email

	if err := uc.DB.Delete(&user).Error; err != nil {
		log.Printf("删除用户 [数据库删除失败] - 用户ID: %d, 用户名: %s, IP: %s, 耗时: %v, 错误: %v",
			id, username, c.ClientIP(), time.Since(startTime), err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除用户失败: " + err.Error()})
		return
	}

	log.Printf("删除用户 [成功] - 用户ID: %d, 用户名: %s, 邮箱: %s, IP: %s, 耗时: %v",
		id, username, email, c.ClientIP(), time.Since(startTime))

	c.JSON(http.StatusNoContent, nil)
}
